'''
    Description: embustest remote command client lib.
    Author:      ycl
    Date:        2023-7-14
'''

import socket
import json
import threading

class EMRC_Client:
    def __init__(self, server_ip='192.168.10.66', server_port=12000) -> None:
        self.server_ip = server_ip
        self.server_port = server_port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    
        pass
    
    def _send(self, msg="udp msg"):
        self.sock.sendto(msg.encode('utf8'), (self.server_ip,self.server_port))
        return

    def candump_subscribe(self, recv_func):
        dic = {'cmd':'candump_subscribe'}
        self._send(json.dumps(dic))
        self.candump_recv_func = recv_func
        return

    def lindump_subscribe(self, recv_func):
        dic = {'cmd':'lindump_subscribe'}
        self._send(json.dumps(dic))
        self.lindump_recv_func = recv_func
        return
        
    def cansend(self, ch='1~16',loop=1,interval=1000, frame="101#std#e#8#ABCD1234CDEF5678"):
        "发送can/fd报文"
        dic = {'cmd':'cansend','paras':{'channel':ch, 'loop':loop, 'interval':interval,'frame':frame}}    
        self._send(json.dumps(dic))
        return
    
    def process(self):
        self._send()  # 先发一个随机消息，避免未发送过消息，recvfrom提示WinError 10022    
        while True:            
            recv_msg, addr = self.sock.recvfrom(1024)
            # print('msg from server:', recv_msg.decode('utf8'))
            dic = json.loads(recv_msg)        
            if(dic['cmd'] == 'candump'):
                # print('candump: ', dic)
                self.candump_recv_func(dic['paras'])
            elif (dic['cmd'] == 'lindump'):
                # print('lindump: ', dic)
                self.lindump_recv_func(dic['paras'])
        
    def start(self):
        thread = threading.Thread(target=self.process)
        thread.start()
        pass
        
'''
/* support cmd define(follow from: embustest cml):
1.PC->RMU
.cansend
{
    "cmd":"cansend",     
    "paras":{             
        "channel":"1~15", //表示1~15通道轮流发送
        "loop":5,       //表示发送的循环次数
        "interval": 1000,   //表示发送的间隔,单位ms
        "frame":"101#std#e#8#ABCD1234CDEF5678" //发送的帧数据:101-canid(十六进制);std-标准帧,fd-canfd帧;e-ide_flag;8-dlc
    }
}

.订阅candump消息
{
    "cmd":"candump_subscribe"
}

.订阅lindump消息
{
    "cmd":"candump_subscribe"
}

2.RMU->PC
.candump
{
    "cmd":"candump",
    "paras":{
        "id":1,   //canid(十进制)
        "channel": 1,
        "direction":1, //1-send, 0-recv
        "type":"can", //0-can; 1-canfd
        "dlc":8,      //data length,unit:byte
        "data":"ABCD1234CDEF5678"  //data
    }
}

.lindump
{
    "cmd":"lindump",
    "paras":{
        "id":1,
        "channel": 1,
        "direction":1, //1-send, 0-recv        
        "dlc":8,      //data length,unit:byte
        "data":"ABCD1234CDEF5678"  //data
    }
}
*/
'''